home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / pcb-1.000 / pcb-1 / pcb-1.3 / log.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  6KB  |  183 lines

  1. /*
  2.  *                            COPYRIGHT
  3.  *
  4.  *  PCB, interactive printed circuit board design
  5.  *  Copyright (C) 1994,1995 Thomas Nau
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *  Contact addresses for paper mail and Email:
  22.  *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
  23.  *  Thomas.Nau@rz.uni-ulm.de
  24.  *
  25.  */
  26.  
  27. static    char    *rcsid = "$Header: /sda4/users/nau/src/pcb/RCS/log.c,v 2.2 1994/10/03 15:51:30 nau Exp nau $";
  28.  
  29. /* logging routines
  30.  */
  31. #include <errno.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34.  
  35. #include "global.h"
  36.  
  37. #include "data.h"
  38. #include "log.h"
  39.  
  40. #include <X11/Shell.h>
  41. #include <X11/Xaw/AsciiText.h>
  42.  
  43. /* ---------------------------------------------------------------------------
  44.  * some local identifiers
  45.  */
  46. static    Widget        Popup,            /* the popup shell */
  47.                     LogWidget;        /* the text widget */
  48. static    XtInputId    LogInputID;        /* input ID of log window */
  49. static    Boolean        Maped = False;    /* maped state of log window */
  50.  
  51. /* ---------------------------------------------------------------------------
  52.  * some external identifiers
  53.  */
  54. extern    int            errno;
  55.  
  56. /* ---------------------------------------------------------------------------
  57.  * some local prototypes
  58.  */
  59. static    void    LogEvent(Widget, XtPointer, XEvent *, Boolean *);
  60. static    void    ReadData(XtPointer, int *, XtInputId *);
  61. static    void    AppendToLog(char *, int);
  62.  
  63. /* ---------------------------------------------------------------------------
  64.  * creates a new window to display logging messages
  65.  */
  66. void InitLogWindow(Widget Parent, int Filedes)
  67. {
  68.         /* create shell window with text-widget and exit button */
  69.     Popup = XtVaCreatePopupShell("log", topLevelShellWidgetClass,
  70.         Parent,
  71.         NULL);
  72.  
  73.     LogWidget = XtVaCreateManagedWidget("text", asciiTextWidgetClass,
  74.         Popup,
  75.         XtNeditType, XawtextRead,
  76.         XtNscrollHorizontal, XawtextScrollWhenNeeded,
  77.         XtNscrollVertical, XawtextScrollWhenNeeded,
  78.         NULL);
  79.  
  80.         /* bring all stuff to the screen */
  81.     XtPopup(Popup, XtGrabNone);
  82.  
  83.         /* register 'delete window' message */
  84.     XSetWMProtocols(Dpy, XtWindow(Popup), &WMDeleteWindowAtom, 1);
  85.  
  86.         /* register event handler for map and unmap (icon) */
  87.     XtAddEventHandler(Popup,
  88.         StructureNotifyMask, False, (XtEventHandler) LogEvent, NULL);
  89.  
  90.         /* register new input source */
  91.     LogInputID = XtAppAddInput(Context, Filedes,
  92.         (XtPointer) XtInputReadMask, (XtInputCallbackProc) ReadData, NULL);
  93. }
  94.  
  95. /* ----------------------------------------------------------------------
  96.  * event handler for map and unmap events
  97.  * used to determine the icon state of the log window
  98.  */
  99. static void LogEvent(Widget W, XtPointer ClientData,
  100.     XEvent *Event, Boolean *Flag)
  101. {
  102.     switch(Event->type)
  103.     {
  104.         case MapNotify:        /* window state changes to visible */
  105.             Maped = True;
  106.             break;
  107.  
  108.         case UnmapNotify:    /* window state changes to invisible or iconified */
  109.             Maped = False;
  110.             break;
  111.     }
  112. }
  113.  
  114. /* ---------------------------------------------------------------------------
  115.  * this function is called from the X dispatcher when a filedescriptor
  116.  * is ready for reading.
  117.  * Our stderr was 'duped' to a pipe of which the read end is registered
  118.  * as an additional X input source
  119.  */
  120. static void ReadData(XtPointer ClientData, int *Source, XtInputId *ID)
  121. {
  122.     char    buffer[512];    /* data buffer */
  123.     int        n;                /* number of bytes read to buffer */
  124.  
  125.         /* read data and do some error processing */
  126.     switch(n = read(*Source, buffer, sizeof(buffer) -1))
  127.     {
  128.         case -1:    /* do nothing on signal, remove source on error */
  129.             if (errno != EINTR)
  130.                 XtRemoveInput(*ID);
  131.             break;
  132.  
  133.         case 0:        /* EOF condition */
  134.             XtRemoveInput(*ID);
  135.             break;
  136.  
  137.         default:    /* copy data to text widget */
  138.             XBell(Dpy, Settings.Volume);
  139.             AppendToLog(buffer, n);
  140.             break;
  141.     }
  142. }
  143.  
  144. /* ---------------------------------------------------------------------------
  145.  * append text to log 
  146.  * hints have been taken from 'xconsole.c' by Keith Packard, MIT X Consortium
  147.  */
  148. static void AppendToLog(char *Buffer, int Length)
  149. {
  150.     XawTextPosition        current,        /* cursor position in text widget */
  151.                         last;            /* last position in widget */
  152.     XawTextBlock        block;            /* description of text */
  153.     Widget                source;            /* source widget within text widget */
  154.  
  155.         /* start searching from the start till the end to get
  156.          * the current text size
  157.          */
  158.     source = XawTextGetSource(LogWidget);
  159.     current = XawTextGetInsertionPoint(LogWidget);
  160.     last = XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True);
  161.  
  162.         /* insert all new data by:
  163.          *   getting the source widget within the text widget
  164.          *   changing the edit mode to XawtextEdit
  165.          *   inserting data by calling XawTextReplace()
  166.          *   changing the edit mode back to XawtextRead
  167.          */
  168.     block.ptr = Buffer;
  169.     block.firstPos = 0;
  170.     block.length = Length;
  171.     block.format = FMT8BIT;
  172.     XtVaSetValues(source, XtNeditType, XawtextEdit, NULL);
  173.     XawTextReplace(LogWidget, last, last, &block);
  174.     XtVaSetValues(source, XtNeditType, XawtextRead, NULL);
  175.     if (current == last)
  176.         XawTextSetInsertionPoint(LogWidget, last +block.length);
  177.  
  178.         /* change from icon to visible window if necessary */
  179.     if (!Maped)
  180.         XMapRaised(Dpy, XtWindow(Popup));
  181. }
  182.  
  183.